package com.wxpay.client.util;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import com.boxin.ims.modules.wechat.entity.WXPay;
import com.boxin.ims.modules.wechat.entity.WeChat;
import com.boxin.ims.modules.wechat.entity.WechatMember;
import com.boxin.ims.modules.wechat.service.WXPayService;
import com.boxin.ims.modules.wechat.service.WeChatService;
import com.boxin.ims.modules.wechat.utils.ScoreUtils;
import com.boxin.ims.modules.wechat.utils.XMLUtils;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.wxpay.client.util.MoneyUtils;


@Service
public class WelfareUtils   implements ApplicationContextAware{

	private static  WXPayService wXPayService;
	private static  WeChatService weChatService;
	
	/**
	 * 发送现金红包【提供方和发送者由外部传入】
	 * @param user	发送红包的商户
	 * @param member	收红包的微信会员
	 * @param orderNNo	发送红包的本地记录单号
	 * @param price		红包金额
	 * @param sendName		发送方姓名
	 * @param wishing	红包祝福语
	 * @param clientIp	调用接口的机器Ip地址
	 * @param actName	活动名称    不能超过10个字
	 * @param remark	备注信息
	 * @return
	 */
	public static Map<String,String> sendHongBaoToMemberByUser(Long userId, WechatMember member,String orderNNo, int price,String sendName,String wishing,String clientIp, String actName,String remark){
		WXPay wx = wXPayService.getByUserId(userId);
		WeChat weChat= weChatService.getWeChatByUserId(userId);

		String postUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("nonce_str", MoneyUtils.buildRandom());//随机字符串
		map.put("mch_billno", orderNNo);//商户订单
		map.put("mch_id", wx.getMchId());//商户号
		map.put("wxappid", weChat.getAppId());//商户appid
		map.put("nick_name", sendName);//提供方名称
		map.put("send_name", sendName);//红包发送者名称
		map.put("re_openid", member.getWechatId());//微信用户openid
		map.put("total_amount", price);//付款金额
		map.put("min_value", price);//最小红包
		map.put("max_value", price);//最大红包
		map.put("total_num", 1);//红包发送总人数
		map.put("wishing", wishing);//红包祝福语
		map.put("client_ip", clientIp);//ip地址
		map.put("act_name", actName);//活动名称
		map.put("remark", remark);//备注
		map.put("sign", MoneyUtils.createSign(map,wx.getApiKey()));//签名
		String result = "";
		Map<String,String> params =  new HashMap<String, String>();
		try {
			System.out.println(MoneyUtils.createXML(map));
			result = MoneyUtils.doSendMoney(postUrl, MoneyUtils.createXML(map),wx.getMchId(),wx.getCertFile());
			Map<String,String> mapTwo = XMLUtils.xml2Map(result);
			
			
			System.out.println("result:"+result);
			
			params.put("send_listid", mapTwo.get("xml.send_listid"));	//微信单号
			params.put("send_time", mapTwo.get("xml.send_time"));		//发放成功时间
			params.put("return_code", mapTwo.get("xml.return_code"));	//返回状态码
			params.put("return_msg", mapTwo.get("xml.return_msg"));		//返回信息
			params.put("result_code", mapTwo.get("xml.result_code"));	//业务结果
			params.put("mch_billno", mapTwo.get("xml.mch_billno"));		//商户订单号
			params.put("err_code", mapTwo.get("xml.err_code"));			//错误代码
			params.put("err_code_des", mapTwo.get("xml.err_code_des"));	//错误代码描述
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return params;
	}
	
	/**
	 * 企业付款接口【企业红包】
	 *@author xiaoqian
	 * @param user
	 * @param member
	 * @param orderNNo
	 * @param price
	 * @param sendName
	 * @param wishing
	 * @param clientIp
	 * @param actName
	 * @param remark
	 * @return
	 * 2015-7-1上午10:01:57
	 */
	public static Map<String,String> sendPayToMemberByUser(User user, WechatMember member,String orderNNo, int price,String clientIp,String desc){
		WXPay wx = wXPayService.getByUserId(user.getId());
		WeChat weChat= weChatService.getWeChatByUserId(user.getId());

		String postUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("mch_appid", weChat.getAppId());//商户appid
		map.put("mchid", wx.getMchId());//商户号
//		map.put("sub_mch_id", wx.getMchId());//微信支付分配的子商户号，受理模式下必填 
//		map.put("device_info", wx.getMchId());//微信支付分配的终端设备号
		map.put("nonce_str", MoneyUtils.buildRandom());//随机字符串
		map.put("partner_trade_no", orderNNo);//商户订单
		map.put("openid", member.getWechatId());//微信用户openid
		map.put("check_name", "NO_CHECK");//NO_CHECK：不校验真实姓名 		FORCE_CHECK：强校验真实姓名（未实名认证的用户会校验失败，无法转账）		OPTION_CHECK：针对已实名认证的用户才校验真实姓名（未实名认证用户不校验，可以转账成功） 
		//map.put("re_user_name", member.getName());//收款用户真实姓名
		map.put("amount", price);//付款金额
		map.put("desc", desc);//备注
		map.put("spbill_create_ip", clientIp);//ip地址
		System.out.println(map.toString());
		map.put("sign", MoneyUtils.createSign(map,wx.getApiKey()));//签名
		String result = "";
		Map<String,String> params =  new HashMap<String, String>();
		try {
			System.out.println(MoneyUtils.createXML(map));
			result = MoneyUtils.doSendMoney(postUrl, MoneyUtils.createXML(map),wx.getMchId(),wx.getCertFile());
			Map<String,String> mapTwo = XMLUtils.xml2Map(result);
			
			System.out.println("result:"+result);
			
			params.put("payment_no", mapTwo.get("xml.payment_no"));	//企业付款成功，返回的微信订单号
			params.put("payment_time", mapTwo.get("xml.payment_time"));		//企业付款成功时间
			params.put("return_code", mapTwo.get("xml.return_code"));	//返回状态码
			params.put("return_msg", mapTwo.get("xml.return_msg"));		//返回信息
			params.put("result_code", mapTwo.get("xml.result_code"));	//业务结果
			params.put("partner_trade_no", mapTwo.get("xml.partner_trade_no"));		//商户订单号，需保持唯一性
			params.put("err_code", mapTwo.get("xml.err_code"));			//错误代码
			params.put("err_code_des", mapTwo.get("xml.err_code_des"));	//错误代码描述
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return params;
	}
	
	
	/**
	 * 企业付款接口【企业红包】
	 *@author xiaoqian
	 * @param userId
	 * @param realName 真实名
	 * @param member
	 * @param orderNNo
	 * @param price
	 * @param sendName
	 * @param wishing
	 * @param clientIp
	 * @param actName
	 * @param remark
	 * @return
	 * 2015-7-1上午10:01:57
	 */
	public static Map<String,String> sendPayToMember(Long userId,String realName, String wechatId,String orderNo, int price,String clientIp,String desc){
		WXPay wx = wXPayService.getByUserId(userId);
		WeChat weChat= weChatService.getWeChatByUserId(userId);

		String postUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("mch_appid", weChat.getAppId());//商户appid
		map.put("mchid", wx.getMchId());//商户号
//		map.put("sub_mch_id", wx.getMchId());//微信支付分配的子商户号，受理模式下必填 
//		map.put("device_info", wx.getMchId());//微信支付分配的终端设备号
		map.put("nonce_str", MoneyUtils.buildRandom());//随机字符串
		map.put("partner_trade_no", orderNo);//商户订单
		map.put("openid", wechatId);//微信用户openid
		map.put("check_name", "FORCE_CHECK");//NO_CHECK：不校验真实姓名 		FORCE_CHECK：强校验真实姓名（未实名认证的用户会校验失败，无法转账）		OPTION_CHECK：针对已实名认证的用户才校验真实姓名（未实名认证用户不校验，可以转账成功） 
		map.put("re_user_name", realName);//收款用户真实姓名
		map.put("amount", price);//付款金额
		map.put("desc", desc);//备注
		map.put("spbill_create_ip", clientIp);//ip地址
		System.out.println(map.toString());
		map.put("sign", MoneyUtils.createSign(map,wx.getApiKey()));//签名
		String result = "";
		Map<String,String> params =  new HashMap<String, String>();
		try {
			System.out.println(MoneyUtils.createXML(map));
			result = MoneyUtils.doSendMoney(postUrl, MoneyUtils.createXML(map),wx.getMchId(),wx.getCertFile());
			Map<String,String> mapTwo = XMLUtils.xml2Map(result);
			
			System.out.println("result:"+result);
			
			params.put("payment_no", mapTwo.get("xml.payment_no"));	//企业付款成功，返回的微信订单号
			params.put("payment_time", mapTwo.get("xml.payment_time"));		//企业付款成功时间
			params.put("return_code", mapTwo.get("xml.return_code"));	//返回状态码
			params.put("return_msg", mapTwo.get("xml.return_msg"));		//返回信息
			params.put("result_code", mapTwo.get("xml.result_code"));	//业务结果
			params.put("partner_trade_no", mapTwo.get("xml.partner_trade_no"));		//商户订单号，需保持唯一性
			params.put("err_code", mapTwo.get("xml.err_code"));			//错误代码
			params.put("err_code_des", mapTwo.get("xml.err_code_des"));	//错误代码描述
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return params;
	}
	
	/**
	 * 发送现金红包【提供方和发送者从USER中获取】
	 * @param user	发送红包的商户
	 * @param member	收红包的微信会员
	 * @param orderNNo	发送红包的本地记录单号
	 * @param price		红包金额
	 * @param wishing	红包祝福语
	 * @param clientIp	调用接口的机器Ip地址
	 * @param actName	活动名称    不能超过10个字
	 * @param remark	备注信息
	 * @return
	 */
	public static Map<String,String> sendHongBaoToMember(User user, WechatMember member,String orderNNo, int price,String wishing,String clientIp, String actName,String remark){
		WXPay wx = wXPayService.getByUserId(user.getId());
		WeChat weChat= weChatService.getWeChatByUserId(user.getId());

		String postUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("nonce_str", MoneyUtils.buildRandom());//随机字符串
		map.put("mch_billno", orderNNo);//商户订单
		map.put("mch_id", wx.getMchId());//商户号
		map.put("wxappid", weChat.getAppId());//商户appid
		map.put("nick_name", user.getName());//提供方名称
		map.put("send_name", user.getName());//红包发送者名称【对话窗口得到的名称：XXX红包】
		map.put("re_openid", member.getWechatId());//微信用户openid
		map.put("total_amount", price);//付款金额
		map.put("min_value", price);//最小红包
		map.put("max_value", price);//最大红包
		map.put("total_num", 1);//红包发送总人数
		map.put("wishing", wishing);//红包祝福语
		map.put("client_ip", clientIp);//ip地址
		map.put("act_name", actName);//活动名称
		map.put("remark", remark);//备注
		System.out.println(map.toString());
		map.put("sign", MoneyUtils.createSign(map,wx.getApiKey()));//签名
		String result = "";
		Map<String,String> params =  new HashMap<String, String>();
		try {
			System.out.println(MoneyUtils.createXML(map));
			result = MoneyUtils.doSendMoney(postUrl, MoneyUtils.createXML(map),wx.getMchId(),wx.getCertFile());
			Map<String,String> mapTwo = XMLUtils.xml2Map(result);
			
			
			System.out.println("result:"+result);
			
			params.put("send_listid", mapTwo.get("xml.send_listid"));	//微信单号
			params.put("send_time", mapTwo.get("xml.send_time"));		//发放成功时间
			params.put("return_code", mapTwo.get("xml.return_code"));	//返回状态码
			params.put("return_msg", mapTwo.get("xml.return_msg"));		//返回信息
			params.put("result_code", mapTwo.get("xml.result_code"));	//业务结果
			params.put("mch_billno", mapTwo.get("xml.mch_billno"));		//商户订单号
			params.put("err_code", mapTwo.get("xml.err_code"));			//错误代码
			params.put("err_code_des", mapTwo.get("xml.err_code_des"));	//错误代码描述
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return params;
	}
	
	/**
	 * 发送企业代金券
	 *@author xiaoqian
	 * @param user
	 * @param member
	 * @param couponStockId
	 * @param orderNNo
	 * @return
	 * 2015-7-1上午10:00:45
	 */
	public static Map<String,String> sendWXVoucherToMember(User user, WechatMember member,String couponStockId,String orderNNo){
		WXPay wx = wXPayService.getByUserId(user.getId());
		WeChat weChat= weChatService.getWeChatByUserId(user.getId());

		String postUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/send_coupon";
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("nonce_str", MoneyUtils.buildRandom());//随机字符串

		map.put("coupon_stock_id", couponStockId);
		map.put("openid_count", 1);
		map.put("partner_trade_no", orderNNo);
		map.put("openid", member.getWechatId());
		map.put("appid", weChat.getAppId());
		map.put("mch_id", wx.getMchId());
		map.put("nonce_str", MoneyUtils.buildRandom());
		map.put("sign", MoneyUtils.createSign(map,wx.getApiKey()));
		
		String result = "";
		Map<String,String> params =  new HashMap<String, String>();
		try {
			System.out.println(MoneyUtils.createXML(map));
			result = MoneyUtils.doSendMoney(postUrl, MoneyUtils.createXML(map),wx.getMchId(),wx.getCertFile());
			Map<String,String> mapTwo = XMLUtils.xml2Map(result);
			
			params.put("coupon_id",mapTwo.get("xml.coupon_id"));				//代金券id
			params.put("result_code",mapTwo.get("xml.result_code"));			//业务结果
			params.put("success_count",mapTwo.get("xml.success_count"));		//成功记录数
			params.put("failed_count",mapTwo.get("xml.failed_count"));			//失败记录数
			params.put("coupon_stock_id",mapTwo.get("xml.coupon_stock_id"));	//代金券批次id
			params.put("resp_count",mapTwo.get("xml.resp_count"));				//返回记录数
			params.put("ret_code",mapTwo.get("xml.ret_code"));					//返回码
			params.put("return_code",mapTwo.get("xml.return_code"));			//返回状态码
			params.put("err_code",mapTwo.get("xml.err_code"));					//错误代码
			params.put("err_code_des",mapTwo.get("xml.err_code_des"));			//错误代码描述
			params.put("ret_msg",mapTwo.get("xml.ret_msg"));					//返回信息
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("result:"+result);
		
		return params;
	}
	
	/**
	 * 积分兑换现金红包
	 * @param member		会员
	 * @param cashMoney		现金红包值
	 * @param cashScore		积分
	 */
	public static boolean scoreExchangeCashMoney(WechatMember member,Integer cashMoney,Integer cashScore){
		
		boolean flag = false;
		
		String wishing = "您用【"+cashScore+"】积分兑换了【"+cashMoney/100d+"】元现金红包";
		ScoreUtils.addScore(member, -cashScore, wishing);
		
		int i = new Random().nextInt(999);
		String orderNNo = com.thinkgem.jeesite.common.utils.DateUtils.getDateTimeString()+i;
		
		//发红包
		Map<String, String> map = sendHongBaoToMember(member.getUser(), member, orderNNo, cashMoney, wishing, "127.0.0.1", "积分兑换现金红包", wishing);

		if("SUCCESS".equals(map.get("result_code"))){
			flag = true;
		}else{
			flag = false;
		}
		
		return flag;
	}
	
	/**
	 * 积分兑换储值
	 * @param member		会员
	 * @param storedMoney	储值金额
	 * @param storedScore	积分
	 * @return
	 */
	public static boolean scoreExchangeStoredMoney(WechatMember member,Integer storedMoney,Integer storedScore){
		boolean flag = false;
		
		String wishing = "您用【"+storedScore+"】积分兑换了【"+storedMoney/100d+"】元储值";
		ScoreUtils.addScore(member, -storedScore, wishing);
		
		ScoreUtils.addMoney(member, storedMoney, wishing);
		flag = true;
		
		return flag;
	}
	
	/**
	 * 订单退款【 transactionId 或 outTradeNo 二选一(同时存在也可以)】
	 * @param userId
	 * @param refundNo		商户退款单号
	 * @param transactionId	微信订单号	-- 微信生成的订单号，在支付通知中有返回
	 * @param outTradeNo	商户订单号 -- 商户传给微信的订单号
	 * @param totalFee		总金额
	 * @param refundFee		退款金额
	 * @return
	 */
	public static Map<String,String> applyRefund(Long userId, String refundNo, String transactionId, String outTradeNo, Integer totalFee, Integer refundFee){
		WXPay wx = wXPayService.getByUserId(userId);
		WeChat weChat= weChatService.getWeChatByUserId(userId);
		String postUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";//微信退款
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("nonce_str", MoneyUtils.buildRandom());
		map.put("appid", weChat.getAppId());			//公众账号ID
		map.put("mch_id", wx.getMchId());				//商户号
		if(StringUtils.isNotBlank(transactionId)){
			map.put("transaction_id", transactionId);		//微信订单号
		}
		map.put("out_trade_no", outTradeNo);			//商户订单号
		map.put("out_refund_no",refundNo);				//商户退款单号
		map.put("total_fee", totalFee);					//总金额
		map.put("refund_fee", refundFee);				//退款金额
		map.put("op_user_id", wx.getMchId());			//操作员帐号, 默认为商户号
		map.put("sign", MoneyUtils.createSign(map,wx.getApiKey()));
		
		Map<String,String> params =  new HashMap<String, String>();
		try {
			
			String result = MoneyUtils.doSendMoney(postUrl, MoneyUtils.createXML(map),wx.getMchId(),wx.getCertFile());
			System.out.println("result:"+result);
			
			Map<String,String> mapTwo = XMLUtils.xml2Map(result);
			params.put("return_code", mapTwo.get("xml.return_code"));	//返回状态码:SUCCESS/FAIL
			params.put("return_msg", mapTwo.get("xml.return_msg"));		//返回信息
			params.put("result_code", mapTwo.get("xml.result_code"));	//业务结果:SUCCESS退款申请接收成功，结果通过退款查询接口查询
			params.put("err_code", mapTwo.get("xml.err_code"));			//错误代码
			params.put("err_code_des", mapTwo.get("xml.err_code_des"));	//错误代码描述
			
			params.put("out_refund_no", mapTwo.get("xml.out_refund_no"));	//商户退款单号
			params.put("out_trade_no", mapTwo.get("xml.out_trade_no"));		//商户订单号
			params.put("fee_type", mapTwo.get("xml.fee_type"));			//订单金额货币种类
			params.put("total_fee", mapTwo.get("xml.total_fee"));			//订单总金额
			params.put("cash_fee", mapTwo.get("xml.cash_fee"));				//现金支付金额
			params.put("cash_refund_fee", mapTwo.get("xml.cash_refund_fee"));	//现金退款金额
			params.put("refund_id", mapTwo.get("xml.refund_id"));				//微信退款单号
			params.put("refund_fee", mapTwo.get("xml.refund_fee"));				//退款金额
			params.put("refund_channel", mapTwo.get("xml.refund_channel"));		//退款渠道
			params.put("transaction_id", mapTwo.get("xml.transaction_id"));		//微信订单号
			params.put("coupon_refund_id", mapTwo.get("xml.coupon_refund_id")); //代金券或立减优惠ID
			params.put("coupon_refund_fee", mapTwo.get("xml.coupon_refund_fee"));//代金券或立减优惠退款金额
			params.put("coupon_refund_count", mapTwo.get("xml.coupon_refund_count"));//代金券或立减优惠使用数量
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return params;
	}
	
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		weChatService  = (WeChatService) applicationContext.getBean("weChatService");
		wXPayService  = (WXPayService) applicationContext.getBean("WXPayService");
	}
	
}
